Ergebnis 1 bis 20 von 21

Thema: Moyas Projekte - Skippy (aka „Basteln wir mal ein intelligentes... Ding.“)

Baum-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #16
    Ich hab mal einen etwas älteren Schnipsel Quelltext bezüglich Wikipedia aufgetrieben. =) (Sorry für das lange Warten, aber wenn man erst eine miese Seminarwoche mitmacht und sich dabei dann auch noch erkältet, hat man wohl Ausreden genug zusammen. ^^)

    Code (Delphi):
    procedure TMain.WikiTimerTimer(Sender: TObject);
    begin
    GetWikiArticle;
    Einlese_Memo.Text := WebOrgMemo.Text;
    Texteinlesen('wiki');
    end;

    Das Einlesen von Wikipedia geschieht timergesteuert immer mal wieder. (In der Version, aus der der Quelltext stammt, alle fünf Sekunden.)
    Es wird nicht nach einem bestimmten Artikel gesucht, was für ein späteres Stadium sicherlich interessant wäre (man fragt zum Beispiel etwas zu irgendeinem Thema, der Bot hat keine Ahnung und stellt daher erstmal kurze Recherchen an, und spuckt dann in Sekundenschnelle eine perfekte Antwort auf eine Frage aus, die er selbst zuvor noch nicht kannte... tjaja, Utopien sind toll. ^^), sondern erstmal nur ein zufälliger Artikel gewählt. Der Sinn des ganzen ist es, weniger Nutzereingaben machen zu müssen, um dem Bot Syntax und Vokabular der jeweiligen Sprache sowie einige Zusammenhänge klarzumachen, und das ganze eher automatisiert ablaufen zu lassen. Wer hat schon Lust, auf seinen Bot wie auf ein kleines Kind jahrelang einzureden, nur damit der nach sechs Jahren Arbeit im Bestfall reif für die Grundschule ist?
    Um Nutzereingaben in dieser frühen Phase, die für den Nutzer allenfalls frustrierend ist, da halt noch nicht allzu viel sinnvolles ausgegeben wird, aber trotzdem stets sinnvolle Dinge eingegeben werden müssen, in der vagen Hoffnung, dass der Geist in der Maschine irgendwann mal etwas davon versteht, noch weiter herabsetzen zu können, ist auch die Möglichkeit denkbar, nicht nur zufällige Artikel von Wikipedia einzulesen, sondern das ganze beispielsweise auch mit jeder Literatur von Kurzgeschichten bis hin zu Romanen zu füttern.
    Doch wie funktioniert nun dieses unglaublich umwerfende, da unheimlich überschaubare Quelltextstückchen von sechs Zeilen?
    Bei GetWikiArticle; wird zunächst ein zufälliger Artikel von Wikipedia heruntergeladen, sowie in eine lesbare Form gebracht (was meistens zur Folge hat, dass 90% geschnitten werden, aber dazu später mehr).
    Anschließend wird das Memo, das normalerweise die Nutzereingaben annimmt, mit dem resultierenden Text gefüllt, und schließlich, <tadaa!>, wird der Text eingelesen - mit dem Parameter 'wiki', damit der Bot weiß, dass das von Wikipedia stammt, und nicht aus der Feder des Nutzers.

    Nun gehen wir mal Hals über Kopf direkt in die Prozedur:
    Code (Delphi):
    procedure TMain.getWikiArticle;
    var vars, varss: string;
        vari, varii: Integer;
    Label Lab1, Lab2, Ende;

    Man nehme ein paar langweilige und nicht weiter erwähnenswerte da vollkommen unaussagekräftige Variablen- und Sprungzieldeklarationen...

    Code (Delphi):
    RescueTimer.Enabled := false;
    RescueTimer.Enabled := true;

    ... gehe sicher, dass für den Notfall - wie auch immer dieser aussehen mag - irgendeine Form von Rettung in Sicht ist, wobei diese vorher auf false gesetzt wird, damit sie von vorn zu zählen anfängt, bis sie losretten soll...

    Code (Delphi):
    Lab2:
    if Problem_Panel.Visible then
    goto Ende;

    ... werde sich darüber klar, dass es bei einem bereits bestehenden Problem definitiv nicht der richtige Zeitpunkt ist, um ein bisschen auf Wikipedia herumzulesen...

    Code (Delphi):
    WebOrgMemo.Text := GetHTML('http://de.wikipedia.org/wiki/Spezial:Zuf%C3%A4llige_Seite');

    ... lade dann in freudiger Erwartung einen zufälligen Artikel als HTML-Datei von Wikipedia direkt in ein jungfräuliches Memo...

    Code (Delphi):
    varss := StringReplace(WebOrgMemo.Text, #10, #13#10, [rfReplaceAll]);
    varss := StringReplace(varss, #13#13#10, #13#10, [rfReplaceAll]);
    varss := StringReplace(varss, 'ä', 'ä', [rfReplaceAll]);
    varss := StringReplace(varss, 'ö', 'ö', [rfReplaceAll]);
    varss := StringReplace(varss, 'ü', 'ü', [rfReplaceAll]);
    //varss := StringReplace(varss, '', 'Ä', [rfReplaceAll]);
    varss := StringReplace(varss, 'Ã&#8211;', 'Ö', [rfReplaceAll]);
    varss := StringReplace(varss, 'é', 'é', [rfReplaceAll]);
    varss := StringReplace(varss, 'â&#8364;&#8482;', '''', [rfReplaceAll]);
    varss := StringReplace(varss, 'Ã&#339;', 'Ü', [rfReplaceAll]);
    varss := StringReplace(varss, 'Ã&#376;', 'ß', [rfReplaceAll]);
    varss := StringReplace(varss, 'â&#8364;&#8220;', '-', [rfReplaceAll]);
    varss := StringReplace(varss, 'â&#8364;&#382;', '"', [rfReplaceAll]);
    varss := StringReplace(varss, 'â&#8364;&#339;', '"', [rfReplaceAll]);
    varss := StringReplace(varss, #9, '', [rfReplaceAll]);

    ... ersetze das ein- oder andere kryptische Zeichen, dass einem dabei wohl über den Weg laufen mag, durch ein sehr viel tolleres Zeichen...

    Code (Delphi):
    Lab1:
    if Problem_Panel.Visible then
    goto Ende;
    if (not (pos('<', varss) = 0)) and (pos('<', varss) < pos('>', varss)) then
    begin
    vars := copy(varss, pos('<', varss) + 1, pos('>', varss) - (pos('<', varss) + 1));
    if vars = 'br' then
    begin
    varss := copy(varss, 1, pos('<', varss) - 1) + #13#10 + copy(varss, pos('>', varss) + 1, Length(varss));
    goto Lab1;
    end;
    varss := copy(varss, 1, pos('<', varss) - 1) + copy(varss, pos('>', varss) + 1, Length(varss));
    goto Lab1;
    end;

    ... ignoriere jede Form von Textformatierung, da die unser Bot sowieso nicht lesen kann - außer den Absätzen, die sind natürlich gaaanz wichtig - indem man alles, was zwischen „<“ und „>“ steht, wegfallen lässt, wobei man stets darauf achtet, bei einem Problem nicht auch noch weiterzumachen...

    Code (Delphi):
    WebOrgMemo.Text := varss;

    ... setze in einem Anfall von purem Optimismus das Ausgabememo dieser Prozedur schon mal auf den bisherigen Zwischenwert...

    Code (Delphi):
    for vari := 0 to WebOrgMemo.Lines.Count do
    if WebOrgMemo.Lines.Strings[vari] = 'Diese Seite ist eine Begriffsklärung zur Unterscheidung mehrerer mit demselben Wort bezeichneter Begriffe.' then
    goto Lab2;

    ... überprüfe, ob es sich bei der Seite nur um eine Begriffsunterscheidungsseite handelt, was uns nicht wirklich gefiele, da man auf einer solchen Seite nicht allzuviel lernt, weswegen wir in diesem Fall zum Laden eines anderen zufälligen Artikels zurückspringen...

    Code (Delphi):
    vari := -1;
    repeat
    Inc(vari);
    until (WebOrgMemo.Lines.Strings[vari] = 'Wechseln zu: Navigation, Suche') or (vari > WebOrgMemo.Lines.Count);
    if WebOrgMemo.Lines.Strings[vari] = 'Wechseln zu: Navigation, Suche' then
    begin
    varss := '';
    for vari := vari + 1 to WebOrgMemo.Lines.Count - 1 do
    varss := varss + WebOrgMemo.Lines.Strings[vari] + #13#10;
    WebOrgMemo.Text := StringReplace(varss, #13#10#13#10, #13#10, [rfReplaceAll]);
    end;

    ... schneide alles ab, was über dem magischen String „Wechseln zu: Navigation, Suche“ liegt, sollte dieser vorkommen...

    Code (Delphi):
    if Problem_Panel.Visible then
    goto Ende;

    ... überprüfe, weil es so schön ist, glatt nochmal, ob nicht inzwischen woanders im Programm ein Problem aufgetaucht sein könnte, was uns davon abhält, hier weiterzumachen...

    Code (Delphi):
    vari := 0;
    repeat
    if copy(WebOrgMemo.Lines.Strings[vari], 1, 12) = '[Bearbeiten]' then
    WebOrgMemo.Lines.Delete(vari)
    else
    if WebOrgMemo.Lines.Strings[vari] = '' then
    WebOrgMemo.Lines.Delete(vari)
    else
    Inc(vari);
    until (pos('Von "', WebOrgMemo.Lines.Strings[vari]) > 0) or (pos('Bitte beachten Sie den', WebOrgMemo.Lines.Strings[vari]) > 0) or (pos('Kategorie: ', WebOrgMemo.Lines.Strings[vari]) > 0) or (pos('Kategorien: ', WebOrgMemo.Lines.Strings[vari]) > 0) or (pos('[Bearbeiten] Werk', WebOrgMemo.Lines.Strings[vari]) > 0) or (pos('[Bearbeiten] Literatur', WebOrgMemo.Lines.Strings[vari]) > 0) or (pos('[Bearbeiten] Fernsehen', WebOrgMemo.Lines.Strings[vari]) > 0) or (pos('[Bearbeiten] Filmographie', WebOrgMemo.Lines.Strings[vari]) > 0) or (pos('[Bearbeiten] siehe auch', WebOrgMemo.Lines.Strings[vari]) > 0) or (pos('[Bearbeiten] Veröffentlichungen', WebOrgMemo.Lines.Strings[vari]) > 0) or (pos('[Bearbeiten] Quellen', WebOrgMemo.Lines.Strings[vari]) > 0) or (pos('[Bearbeiten] Einzelnachweise', WebOrgMemo.Lines.Strings[vari]) > 0) or (pos('[Bearbeiten] Weblinks', WebOrgMemo.Lines.Strings[vari]) > 0) or allesfreiab(vari, WebOrgMemo.Lines);

    ... nehme alle Zeilen heraus, die ein [Bearbeiten] zu Anfang haben, weil die eh Mist sind und nur Überschriften, und Überschriften stören unseren Bot nur, sowie alle Zeilen, die leer sind, und sowieso alle Zeilen, die nach gewissen Schlüsselstrings kommen, da danach stets nur Listen kommen, die unserem Bot auch nicht helfen, die Sprache besser zu erlernen ...

    Code (Delphi):
    if copy(WebOrgMemo.Lines.Strings[vari], 1, 12) = '[Bearbeiten]' then
    begin
    WebOrgMemo.Lines.Delete(vari);
    Dec(vari);
    end;

    ... schaue nochmal, ob wir nicht eine vergessen haben - geht ja schnell mal im Eifer des Gefechts =) ...


    Code (Delphi):
    varss := '';
    for vari := 0 to vari do
    varss := varss + WebOrgMemo.Lines.Strings[vari] + #13#10;
    WebOrgMemo.Text := StringReplace(varss, #13#10#13#10, #13#10, [rfReplaceAll]);

    ... fülle den Text nochmal vom Memo in den String um und wieder zurück, um überflüssige Zeilen zu eliminieren und weils halt so viel Spaß macht...

    Code (Delphi):
    vari := -1;
    repeat
    Inc(vari);
    until (WebOrgMemo.Lines.Strings[vari] = 'Inhaltsverzeichnis') or (vari > WebOrgMemo.Lines.Count);
    if WebOrgMemo.Lines.Strings[vari] = 'Inhaltsverzeichnis' then
    begin
    varss := '';
    for varii := 0 to vari - 1 do
    varss := varss + WebOrgMemo.Lines.Strings[varii] + #13#10;

    ... nehme dabei dann noch allen Text, der vor dem Inhaltsverzeichnis vorhanden ist, falls denn eins vorhanden ist...

    Code (Delphi):
    repeat
    Inc(vari);
    until (WebOrgMemo.Lines.Strings[vari] = '//') or (vari > WebOrgMemo.Lines.Count);
    if WebOrgMemo.Lines.Strings[vari] = '//' then
    begin
    for varii := vari + 1 to WebOrgMemo.Lines.Count - 1 do
    varss := varss + WebOrgMemo.Lines.Strings[varii] + #13#10;
    WebOrgMemo.Text := StringReplace(varss, #13#10#13#10, #13#10, [rfReplaceAll]);
    end;
    end;

    ... sowie allen Text danach, denn das Inhaltsverzeichnis selbst brauchen wir ja nicht, da wir ja den Inhalt haben...

    Code (Delphi):
    if Problem_Panel.Visible then
    goto Ende;

    ... man kennt es schon ^^ ...

    Code (Delphi):
    varss := WebOrgMemo.Text;
    while (not (pos('[', varss) = 0)) and (pos('[', varss) < pos(']', varss)) do
    varss := copy(varss, 1, pos('[', varss) - 1) + copy(varss, pos(']', varss) + 1, Length(varss));

    ... kürze noch schnell alles, was in eckigen Klammern steht, denn Dinge in eckigen Klammern sind nie wichtig und meistens nur Angaben zu den Quellen, die unseren Bot herzlich überhaupt nicht interessieren...

    Code (Delphi):
    while (not (pos('(', varss) = 0)) and (pos('(', varss) < pos(')', varss)) do
    begin
    vars := copy(varss, pos('(', varss) + 1, pos(')', varss) - (pos('(', varss) + 1));
    if copy(vars, 1, 2) = '* ' then
    begin
    if pos('â&#8364;', vars) = 0 then
    varss := copy(varss, 1, pos('(', varss) - 1) + ', geboren am ' + copy(vars, 3, Length(vars)) + ',' + copy(varss, pos(')', varss) + 1, Length(varss))
    else
    varss := copy(varss, 1, pos('(', varss) - 1) + ', geboren am ' + copy(copy(vars, 3, Length(vars)), 1, pos(';', copy(vars, 3, Length(vars))) - 1) + ' und verstorben am ' + copy(copy(vars, 3, Length(vars)), pos('â&#8364;', copy(vars, 3, Length(vars))) + 3, Length(vars)) + ',' + copy(varss, pos(')', varss) + 1, Length(varss));
    end
    else
    varss := copy(varss, 1, pos('(', varss) - 1) + copy(varss, pos(')', varss) + 1, Length(varss));
    end;

    ... bringe die Angabe über Geburtstag und Todestag, sofern es sich bei dem Artikel um einen handelt, der sich um eine Person dreht, in eine botlesbare Form...

    Code (Delphi):
    varss := StringReplace(varss, '   ', ' ', [rfReplaceAll]);
    varss := StringReplace(varss, '  ', ' ', [rfReplaceAll]);
    varss := StringReplace(varss, ' ,', ',', [rfReplaceAll]);
    WebOrgMemo.Text := varss;

    ... lösche noch ein paar Leerzeichen, die bei den zurückliegenden radikalen Ausschneideaktionen zurückgeblieben sind und den lieben Bot nur stören würden...

    Code (Delphi):
    if (pos('.', WebOrgMemo.Lines.Strings[0]) = 0) and (pos('!', WebOrgMemo.Lines.Strings[0]) = 0) and (pos('?', WebOrgMemo.Lines.Strings[0]) = 0) then
    WebOrgMemo.Lines.Delete(0);

    ... lösche die erste Zeile, sofern sie kein Satzzeichen enthält, weil die erste Zeile sowieso langweilig ist und in dem speziellen Fall sicherlich eher eine Überschrift als einen Satz darstellt, aus dem der Bot etwas Sinnvolles erfahren könnte...

    Code (Delphi):
    Ende:
    RescueTimer.Enabled := false;
    Problem_Panel.Visible := false;
    end;

    ... und freue sich schließlich, dass man ans Ende gelangt ist, was man auch gleich dem ganzen Rest des Programms mitteilt, indem man die Notfallrettung abbestellt und Probleme als nichtexistent bezeichnet.

    Ich denke, man versteht nun einigermaßen, wieso gefühlte 90% eines jeden Artikels gelöscht werden: Überschriften werden nicht gebraucht, Inhaltsverzeichnisse auch nicht, jedwede Art von Liste ist für das Lernen der Sprache nicht so geeignet wie vernünftige Sätze und wird gelöscht und schließlich fallen auch alle Texthervorhebungen weg.
    Somit sind wir nun an dem Punkt, dass unser Bot einen kurzen, knappen Text geschickt bekommt, der vor Sinn und Syntax sowie Vokabular nur so strotzt und ihm hoffentlich in ganz kurzer Zeit das Sprechen beibringt.

    Vielen Dank für Ihre Aufmerksamkeit, ich bin Moyaccercchi, und Sie lasen einen Artikel zu Skippy, dem Buschkänguru der künstlichen Intelligenz.

    Geändert von Moyaccercchi (17.01.2010 um 17:00 Uhr)

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •